package bold.deposit.interception;

import bold.deposit.useful.RequestUtil;
import bold.deposit.useful.Result;
import bold.deposit.useful.valid.ValidException;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import redis.clients.jedis.exceptions.JedisConnectionException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringWriter;

@Log4j2
@Component
public class ExceptionHandler implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exp) {
        ModelAndView modelAndView = new ModelAndView();
        MappingJackson2JsonView view = new MappingJackson2JsonView();

        Result result = new Result();
        if (exp instanceof Authorize.NotLogin) {
            result.setCode(401);
            result.setMsg("请登录");
        } else if (exp instanceof Authorize.LoginInvalidity) {
            result.setCode(402);
            result.setMsg("登录失效");
        } else if (exp instanceof Authorize.NoMapping) {
            result.setCode(404);
            result.setMsg("请求不存在");
        } else if (exp instanceof ValidException) {
            result.setCode(501);
            result.setMsg(exp.getMessage());
        } else if (exp instanceof JedisConnectionException) {
            result.setCode(502);
            result.setError("redis 挂了");
        } else {
            result.setCode(500);
            result.setMsg("系统提示，代码：500！");
            log.error(" 500 错误 url: " + request.getRequestURI() + " " + RequestUtil.getAllMap(request).toString(),exp);
//            log.error(exp.getMessage());
//            log.error(stackTraceString(exp));
//            exp.printStackTrace();
            result.setError(stackTraceString(exp));
        }
        view.setAttributesMap(result);
        modelAndView.setView(view);
        return modelAndView;
    }

    private static String stackTraceString(Throwable e) {
        StringWriter writer = new StringWriter();
        e.printStackTrace(new PrintWriter(writer, true));
        return writer.toString();
    }
}